<template>
    <div class="menu-container" v-if="loadOver">
        <!-- 查询模块 -->
        <div class="header">
            <div class="query">
                <!-- <el-form ref="queryForm" :inline="true" :model="queryForm">
                    <el-form-item prop="menuName">
                        <el-input
                            placeholder="菜单名称"
                            v-model="queryForm.username"
                        ></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" @click="query"
                            >查询</el-button
                        >
                    </el-form-item>
                </el-form> -->
            </div>
            <div class="operation">
                <el-button type="primary" @click="Add"> 新建 </el-button>
                <el-button type="success" @click="Refresh"> 刷新 </el-button>
                <el-button type="primary" @click="Edit"> 编辑 </el-button>
                <el-button type="danger" @click="Delete"> 删除 </el-button>
                <el-button type="primary" @click="SortMenu"> 排序 </el-button>
            </div>
        </div>
        <div class="data">
            <!-- 表格 -->
            <el-table
                ref="table"
                v-loading="loading"
                :data="list"
                border
                row-key="id"
                @row-click="handleRowClick"
                :tree-props="{
                    children: 'children',
                    hasChildren: 'hasChildren',
                }"
                fit
                @selection-change="handleSelectionChange"
            >
                <el-table-column type="selection" width="55" align="center">
                </el-table-column>
                <el-table-column align="center" label="序号" width="95">
                    <template slot-scope="scope"> </template>
                </el-table-column>

                <el-table-column label="菜单名称" prop="menuName">
                </el-table-column>
                <el-table-column label="路由名称" prop="name">
                </el-table-column>
                <el-table-column label="是否缓存页面">
                    <template slot-scope="scope">
                        <el-switch
                            v-model="scope.row.noCache"
                            :active-value="1"
                            :inactive-value="0"
                            disabled
                        >
                        </el-switch>
                    </template> </el-table-column
                ><el-table-column label="地址" prop="url"> </el-table-column>

                <el-table-column label="状态" align="center" width="80">
                    <template slot-scope="scope">
                        <el-tag
                            :type="
                                scope.row.status == '1' ? 'primary' : 'danger'
                            "
                            >{{
                                scope.row.status
                                    | statusFilter(scope.row.status)
                            }}</el-tag
                        >
                    </template>
                </el-table-column>
                <el-table-column label="图标" align="center">
                    <template slot-scope="scope">
                        <i
                            :class="scope.row.icon"
                            v-if="
                                scope.row.icon &&
                                scope.row.icon.indexOf('el-') !== -1
                            "
                        ></i>
                        <svg-icon
                            :icon-class="scope.row.icon"
                            v-else-if="
                                scope.row.icon &&
                                scope.row.icon.indexOf('el-') == -1
                            "
                        ></svg-icon>
                        <span v-else>无</span>
                    </template>
                </el-table-column>
                <el-table-column label="授权按钮" width="260">
                    <template slot-scope="scope">
                        <el-tag
                            style="margin: 5px"
                            v-for="(btn, index) of getOauthButtons(scope.row)"
                            :key="index"
                            :type="btn.type"
                        >
                            {{ btn.name }}
                        </el-tag>
                    </template></el-table-column
                >
                <el-table-column label="操作" v-if="enableSort" align="center">
                    <template>
                        <div class="handle">
                            <i class="el-icon-rank" style="font-size: 16px"></i>
                        </div>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 分页 -->
            <!-- <el-pagination
                :page-size="limit"
                class="pagination"
                background
                layout="prev, pager, next"
                :total="total"
                @current-change="handlePageChange"
            >
            </el-pagination> -->
        </div>
        <!-- 弹窗 -->
        <el-dialog
            :title="dialogType == 'edit' ? '编辑菜单' : '新建菜单'"
            :visible.sync="dialogVisible"
            :close-on-click-modal="false"
            @open="reloadMenuOption"
            width="50%"
        >
            <div style="padding: 0 25px 0 20px">
                <el-alert type="warning" style="margin-bottom: 15px"
                    >路由名称需要和路由表name一致！！！</el-alert
                >
                <el-form ref="form" :model="menu" label-width="80px">
                    <el-form-item label="菜单名称" prop="menuName">
                        <el-input v-model="menu.menuName"></el-input>
                    </el-form-item>
                    <el-form-item label="路由名称" prop="name">
                        <el-input v-model="menu.name"></el-input>
                    </el-form-item>
                    <el-form-item label="授权按钮" prop="oauth">
                        <el-checkbox-group v-model="menu.oauth">
                            <el-checkbox
                                v-for="button in buttons"
                                :label="button.id"
                                :key="button.id"
                                >{{ button.name }}</el-checkbox
                            >
                        </el-checkbox-group>
                    </el-form-item>
                    <el-form-item label="是否缓存" prop="noCache">
                        <el-switch
                            v-model="menu.noCache"
                            :active-value="1"
                            :inactive-value="0"
                        ></el-switch>
                    </el-form-item>
                    <el-form-item label="地址" prop="url">
                        <el-input v-model="menu.url"></el-input>
                    </el-form-item>
                    <el-form-item label="上级菜单" prop="parentId">
                        <tree-select
                            :options="menuOptions"
                            placeholder="0为一级菜单"
                            v-model="menu.parentId"
                            no-children-text="没有子节点"
                            :normalizer="normalizer"
                        >
                        </tree-select>
                    </el-form-item>
                    <el-form-item label="图标" prop="icon">
                        <div v-if="menu.icon" style="margin-right: 10px">
                            <svg-icon
                                v-if="menu.icon.indexOf('el-') == -1"
                                :icon-class="menu.icon"
                            ></svg-icon>
                            <i :class="menu.icon" style="font-size: 16px"></i>
                            <el-button
                                style="margin-left: 10px"
                                @click="chooseIcon"
                                >更换图标</el-button
                            >
                            <el-button
                                icon="el-icon-close"
                                v-if="menu.icon"
                                @click="menu.icon = ''"
                                circle
                            ></el-button>
                        </div>
                        <el-button v-else @click="chooseIcon"
                            >选择图标</el-button
                        >
                    </el-form-item>
                    <el-form-item label="状态" prop="status">
                        <el-switch
                            v-model="menu.status"
                            :active-value="1"
                            :inactive-value="2"
                        ></el-switch>
                    </el-form-item>
                    <el-form-item label="描述" prop="description">
                        <el-input
                            v-model="menu.description"
                            type="textarea"
                            :rows="3"
                        ></el-input>
                    </el-form-item>
                </el-form>
            </div>
            <span slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="addOrSave">确 定</el-button>
            </span>
        </el-dialog>

        <!-- 选择图标 -->
        <el-dialog :visible.sync="iconDialogVisible" title="选择图标">
            <div style="height: 60vh; overflow: hidden auto">
                <choose-icon @change="setMenuIcon"></choose-icon>
            </div>
        </el-dialog>
    </div>
</template>
<script>
import "@/styles/reset_vue_treeselect.css";
import { LOAD_CHILDREN_OPTIONS } from "@riophae/vue-treeselect";
import { LOAD_ROOT_OPTIONS } from "@riophae/vue-treeselect";
import Sortable from "sortablejs";
import ChooseIcon from "@/components/ChooseIcon";
import { selectAll } from "@/api/button";
import {
    getTreeMenu,
    addMenu,
    deleteMenu,
    updateMenu,
    getChildMenu,
} from "@/api/menu";
const defaultMenu = {
    menuName: "",
    name: "",
    oauth: [],
    noCache: 1,
    url: "",
    parentId: "0",
    icon: "",
    status: 1,
    description: "",
};
export default {
    data() {
        return {
            menu: Object.assign({}, defaultMenu),
            list: [],
            dialogVisible: false,
            dialogType: "new",
            loading: false,
            selectData: [],
            queryForm: {
                menuName: "true",
            },
            buttons: [], // 权限按钮
            iconDialogVisible: false,
            loadOver: false,
            enableSort: false, // 开启排序
            menuOptions: null,
        };
    },
    components: {
        ChooseIcon,
    },
    methods: {
        Add() {
            if (this.selectData.length > 1) {
                return this.$message.error("只能选择一个菜单建立子菜单");
            }
            this.menu = Object.assign({}, defaultMenu);
            // 选中行作为父级
            if (this.selectData[0]) {
                this.menu.parentId = this.selectData[0].id;
            }
            this.dialogType = "new";
            this.dialogVisible = true;
        },
        Refresh() {
            // this.$refs.queryForm.resetFields();
            this.getMenu();
        },
        Edit() {
            if (this.selectData.length == 0) {
                return this.$message.error("未选择任何数据");
            }
            if (this.selectData.length !== 1) {
                return this.$message.error("只能操作一条数据");
            }
            this.dialogType = "edit";
            this.menu = Object.assign({}, this.selectData[0]);
            this.menu.oauth = this.menu.oauth ? this.menu.oauth.split(",") : [];
            this.dialogVisible = true;
        },
        saveMenuSort() {
            console.log("test");
        },
        Delete() {
            if (this.selectData.length == 0) {
                return this.$message.error("未选择任何数据");
            }
            if (this.selectData.length > 1) {
                return this.$message.error("只能选择一条数据");
            }
            this.$confirm("确定要删除这条数据吗?", "删除提醒", {
                confirmButtonText: "确定",
                cancelButtonText: "取消",
                type: "warning",
            })
                .then(async () => {
                    await deleteMenu({
                        id: this.selectData[0].id,
                    });
                    this.Refresh();
                    this.$message({
                        type: "success",
                        message: "删除成功",
                    });
                })
                .catch((err) => {
                    console.error(err);
                });
        },
        async reloadMenuOption() {
            await this.getMenu();
        },
        SortMenu() {
            this.enableSort = !this.enableSort;
            this.$message.info("排序未实现后台逻辑, 只是前端演示");
        },
        loadOptions: async function ({ parentNode, action }) {
            // parentNode.children = null;
            if (action == LOAD_ROOT_OPTIONS) {
                let res = await getChildMenu();
                this.menuOptions = res.data.map((item) => ({
                    id: item.id,
                    children: null,
                    label: item.menuName,
                }));
            } else if (action == LOAD_CHILDREN_OPTIONS) {
                let res = await getChildMenu({
                    id: parentNode.id,
                });
                parentNode.children = res.data.map((item) => ({
                    id: item.id,
                    children: null,
                    label: item.menuName,
                }));
            }
        },
        normalizer(node) {
            return {
                id: node.id,
                label: node.menuName,
                children: node.children,
            };
        },
        setSort() {
            const el = this.$refs.table.$el.querySelectorAll(
                ".el-table__body-wrapper > table > tbody"
            )[0];
            this.sortable = Sortable.create(el, {
                ghostClass: "sortable-ghost", // Class name for the drop placeholder,
                handle: ".handle",
                setData: function (dataTransfer) {
                    // to avoid Firefox bug
                    // Detail see : https://github.com/RubaXa/Sortable/issues/1012
                    dataTransfer.setData("Text", "");
                },
                onEnd: (evt) => {
                    // update list order
                    const targetRow = this.list.splice(evt.oldIndex, 1)[0];
                    this.list.splice(evt.newIndex, 0, targetRow);
                },
            });
        },
        chooseIcon() {
            this.iconDialogVisible = true;
        },
        setMenuIcon(icon) {
            this.menu.icon = icon.icon;
            this.iconDialogVisible = false;
        },
        async getMenu() {
            const res = await getTreeMenu();
            const { data } = res;
            this.list = data;
            this.menuOptions = data;
        },
        handleRowClick(row) {
            this.$refs.table.toggleRowSelection(row);
        },
        handleSelectionChange(selection) {
            this.selectData = selection;
        },
        query() {
            this.getMenu();
        },
        // 获得按钮类别和名称
        getOauthButtons(row) {
            const { oauth } = row;
            if (!oauth) return [];
            const btns = oauth.split(",").map((btnId) => {
                const item = {
                    name: "Error",
                    type: "info",
                };
                const btn = this.buttons.find((item) => item.id == btnId);
                if (btn) {
                    (item.name = btn.name), (item.type = btn.type);
                }
                return btn;
            });
            return btns;
        },
        getData() {
            let requestArr = [getTreeMenu(), selectAll()];
            Promise.all(requestArr).then(([menuRes, btnRes]) => {
                // 获取数据
                this.list = menuRes.data;
                this.menuOptions = menuRes.data;
                this.buttons = btnRes.data;

                this.loadOver = true;
                this.$nextTick(() => {
                    this.setSort();
                });
            });
        },
        async addOrSave() {
            let result;
            // 数组转为字符串
            this.menu.oauth = this.menu.oauth.join(",");
            if (this.dialogType == "edit") {
                result = await updateMenu(this.menu);
            } else {
                result = await addMenu(this.menu);
            }
            const { code } = result;
            if (code == 200) {
                this.$message.success("操作成功");
                this.getMenu();
            } else {
                this.$message.erro("操作失败");
            }
            this.dialogVisible = false;
        },
    },
    created() {
        this.getData();
    },
};
</script>
<style>
.sortable-ghost {
    opacity: 0.8;
    color: #fff !important;
    background: #42b983 !important;
}
.handle {
    cursor: move;
}
</style>
<style lang="scss" scoped>
.menu-container {
    padding: 15px;

    .header {
        display: flex;
        justify-content: space-between;
        margin-bottom: 15px;
    }

    .pagination {
        margin-top: 20px;
    }

    .permission-tree {
        margin-bottom: 30px;
    }
}
</style>
